package com.crazymaker.springcloud.message.core;

import com.crazymaker.springcloud.common.util.ThreadUtil;
import com.crazymaker.springcloud.message.config.ShardingRuleConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.AbstractDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.TimeUnit;

/**
 * 1. 装设模式
 * 目的在于增强被包装类的功能
 * 1
 * 思路步骤
 * 1. 自定义类实现被包装类的所有方法
 * 2. 在定义类中定义被包装类的成员变量
 * 3. 通过构造方法将被包装类赋值
 * 4. 通过所有方法均调用被包装类去实现
 */

@Slf4j
public class DynamicDataSourceDecorator extends AbstractDataSource {


    ShardingRuleConfig shardingRuleConfig;

    private volatile DataSource shardingDataSource;

    public DynamicDataSourceDecorator() {
    }

    public DynamicDataSourceDecorator(ShardingRuleConfig shardingRuleConfig) {
        this.shardingRuleConfig = shardingRuleConfig;
    }

    public DynamicDataSourceDecorator(DataSource shardingDataSource) {
        this.shardingDataSource = shardingDataSource;
    }

    @Override
    public Connection getConnection() throws SQLException {
        return shardingDataSource.getConnection();
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return shardingDataSource.getConnection(username, password);
    }


    public synchronized void changShardingDataSource(DataSource newShardingDataSource) {
        log.info("data source  changed");
        DataSource old = this.shardingDataSource;

        this.shardingDataSource = newShardingDataSource;

        if (null != old && old instanceof AutoCloseable) {
            ThreadUtil.delayRun(() -> {

                        try {
                            ((AutoCloseable) old).close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }, 5, TimeUnit.SECONDS

            );
        }
    }
}
